/*
 ----------------------------------------------------------------------------------
                           "THE BEER-WARE COPYRIGHT LICENSE"
                                     (Revision 43)
                                      -----------
    Rymek [rymek@rymek.org] wrote this file. As long as You retain this notice and
    this file has been sent directly to You by the author, You can do whatever You
    want with this stuff as long as You don't sell or rent it. If we meet some day,
    and You think this stuff is worth it, You can buy me a beer in return :-)
                                                                 __________
                                                                 Paweł Rymaszewski
  ----------------------------------------------------------------------------------
 */

package ui.windows.components.models.resultTableModel;

import constants.MessageConstants;
import constants.UiConstants;
import processing.objects.Result;
import processing.objects.Results;
import utils.properties.Configuration;

import javax.swing.table.AbstractTableModel;
import java.util.Observable;
import java.util.Observer;

/**
 * Result table model for displaying ParsedResults
 *
 * @author rymek
 *         User: rymek
 *         Date: 25.07.11
 *         Time: 12:00
 */
public class ResultTableModel extends AbstractTableModel implements Observer {

    // column names for table
    private final String[] columnNames = {
            UiConstants.COL_MSG_NAME,
            UiConstants.COL_MSG_RECEIVED_DT,
            UiConstants.COL_MSG_RECEIVED_TM,
            UiConstants.COL_MSG_PROCESSING_TIME,
            UiConstants.COL_MSG_STATUS,
            UiConstants.COL_MSG_ID
    };

    private int[] indexes;      // indexes of values in model

    // object that holds actual data added to table
    private volatile Results data;

    /**
     * Returns number of columns for this JTable
     *
     * @return size number of columns for this JTable object
     */
    public synchronized int getColumnCount() {
        return columnNames.length;
    }

    /**
     * Returns number of rows for this
     *
     * @return number of rows in this JTable
     */
    public synchronized int getRowCount() {
        if (this.data == null) return 0;
        return this.data.getResults().get(MessageConstants.MSG_REQUEST).size();
    }

    /**
     * Returns column name at specific index
     *
     * @param col column number
     * @return column name
     */
    public synchronized String getColumnName(int col) {
        return columnNames[col];
    }

    /**
     * Returns value at specific position in JTable
     *
     * @param row row number
     * @param col column number
     * @return value of cell
     */
    public synchronized Object getValueAt(int row, int col) {

        switch (col) {
            case 0: {
                return ((Result) this.data.getResults().get(MessageConstants.MSG_REQUEST).values().toArray()[row]).getMessageInfo().getRequestName();
            }

            case 1: {
                return Configuration.dateFormat.format((((Result) this.data.getResults().get(MessageConstants.MSG_REQUEST).values().toArray()[row]).getMsgRcvDttm()));
            }

            case 2: {
                return Configuration.timeFormat.format((((Result) this.data.getResults().get(MessageConstants.MSG_REQUEST).values().toArray()[row]).getMsgRcvDttm()));
            }

            case 3: {
                return ((Result) this.data.getResults().get(MessageConstants.MSG_REQUEST).values().toArray()[row]).getProcessingTime();
            }

            case 4: {
                return ((Result) this.data.getResults().get(MessageConstants.MSG_REQUEST).values().toArray()[row]).getStatus();
            }

            case 5: {
                return ((Result) this.data.getResults().get(MessageConstants.MSG_REQUEST).values().toArray()[row]).getId();
            }
        }
        return "";
    }

    /**
     * Adds element to this Model
     * and notifies about Model Change
     */
    synchronized void addElement() {
        fireTableDataChanged();
    }

    /**
     * Returns Result at selected row
     *
     * @param rowindex selected row to get
     * @return Selected Result
     */
    public synchronized Result getSelectedRow(int rowindex) {
        return (Result) this.data.getResults().get(MessageConstants.MSG_REQUEST).values().toArray()[rowindex];
    }

    /**
     * Returns table of model's indexes.
     *
     * @return model index table
     */
    public synchronized int[] getIndexes() {
        int rowCount = this.getRowCount();
        if (this.indexes != null) {
            if (this.indexes.length == rowCount) {
                return indexes;
            }
        }
        indexes = new int[rowCount];
        for (int i = 0; i < rowCount; i++) {
            indexes[i] = i;
        }
        return indexes;
    }

    /**
     * Sets data for this model and observes it.
     *
     * @param results Parsed results to watch
     */
    public void setData(Results results) {
        this.data = results;
        this.fireTableDataChanged();
        this.data.addObserver(this);
    }

    /**
     * Fired when Result is added to parsedList
     *
     * @param o   observed Results
     * @param arg argument passed from observed object
     */
    @Override
    public synchronized void update(Observable o, Object arg) {
        this.addElement();
    }
}
